package com.blackcat.demo.sm;

import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.BCUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.GMCipherSpi;

/**
 * 描述 :国密sm2
 *      sm2加解密方式：需要提前生成好一对公钥和私钥，然后加密的时候，用公钥进行加密，解密的时候，用私钥进行解密
 * @author : zhangdahui  2024/5/15 下午2:00
 * @version 1.0
 */
public class SM2Dome {
    public static void main(String[] args) {
        SM2 sm2 = SmUtil.sm2();
        String privateKey = HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(sm2.getPrivateKey()));
        String publicKey = HexUtil.encodeHexStr(((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false));
        System.out.println("公钥 " + publicKey);
        System.out.println("私钥 " + privateKey );

        String password = "123456.123";
        String encryptStr = encrypt(publicKey, password);
        System.out.println("加密 " + encryptStr);
        String decryptStr = decrypt(privateKey, encryptStr);
        System.out.println("解密 " + decryptStr);
    }


    /**
     * 加密
     *
     * @param publicKey 公钥
     * @param data 明文
     * @return 密文
     */
    public static String encrypt(String publicKey, String data) {
        return SmUtil.sm2(null, publicKey)
                .encryptHex(data.getBytes(), KeyType.PublicKey)
                // 加密后，密文前面会有04，需要去掉
                .substring(2);
    }

    /**
     * 解密
     *
     * @param privateKey 私钥
     * @param data 密文
     * @return 明文
     */
    public static String decrypt(String privateKey, String data) {
        // 前端加密是没有04的，所以解析的时候要加04
        data = "04" + data;
        return SmUtil.sm2(privateKey, null)
                .decryptStr(data, KeyType.PrivateKey);
    }


}
